<template>
	<div
		:class="classes"
		@mouseenter="handleMouseenter"
		@mouseleave="handleMouseleave"
		v-click-outside="handleClose"
	>
		<div
			:class="[prefixCls + '-rel']"
			ref="reference"
			@click="handleClick"
			@mousedown="handleFocus(false)"
			@mouseup="handleBlur(false)"
		>
			<slot></slot>
		</div>
		<transition name="fade">
			<div
				:class="popperClasses"
				:style="styles"
				ref="popper"
				v-show="visible"
				@click="handleTransferClick"
				@mouseenter="handleMouseenter"
				@mouseleave="handleMouseleave"
				:data-transfer="transfer"
				v-transfer-dom
			>
				<div :class="[prefixCls + '-content']">
					<div :class="[prefixCls + '-arrow']"></div>
					<div :class="[prefixCls + '-inner']" v-if="confirm">
						<div :class="[prefixCls + '-body']">
							<i class="ivu-icon ivu-icon-ios-help-circle"></i>
							<div :class="[prefixCls + '-body-message']">
								<slot name="title">{{ title }}</slot>
							</div>
						</div>
						<div :class="[prefixCls + '-footer']">
							<i-button type="text" size="small" @click.native="cancel">{{ localeCancelText }}</i-button>
							<i-button type="primary" size="small" @click.native="ok">{{ localeOkText }}</i-button>
						</div>
					</div>
					<div :class="[prefixCls + '-inner']" v-if="!confirm">
						<div
							:class="[prefixCls + '-title']"
							:style="contentPaddingStyle"
							v-if="showTitle"
							ref="title"
						>
							<slot name="title">
								<div :class="[prefixCls + '-title-inner']">{{ title }}</div>
							</slot>
						</div>
						<div :class="[prefixCls + '-body']" :style="contentPaddingStyle">
							<div :class="contentClasses">
								<slot name="content">
									<div :class="[prefixCls + '-body-content-inner']">{{ content }}</div>
								</slot>
							</div>
						</div>
					</div>
				</div>
			</div>
		</transition>
	</div>
</template>
<script lang="ts">
	import Anes from "../base";
	import { Prop, Component, Mixins } from "vue-property-decorator";

	import Popper from "../../mixins/popper";
	import iButton from "../button/button.vue";
	import { ClickOutside } from "../../directives/clickoutside";
	import TransferDom from "../../directives/transfer-dom";
	import { oneOf } from "../../utils/assist";
	import { Placement } from "@popperjs/core";

	const prefixCls = "ivu-poptip";
	@Component({
		name: "Poptip",
		components: { iButton },
		directives: { ClickOutside, TransferDom }
	})
	export default class Poptip extends Mixins(Anes, Popper) {
		@Prop({
			type: String,
			default: "click",
			validator(value) {
				return oneOf(value, ["click", "focus", "hover"]);
			}
		})
		trigger!: string;
		@Prop({ default: "top" }) placement!: Placement;

		@Prop() title!: string | number;
		@Prop({ default: "" }) content!: string | number;
		@Prop() width!: string | number;
		@Prop() okText!: string;
		@Prop() cancelText!: string;
		@Prop() popperClass!: string;
		@Prop() padding!: string;
		@Prop({ default: false }) confirm!: boolean;
		@Prop({ default: false }) wordWrap!: boolean;
		@Prop({ default: false }) disabled!: boolean;

		capture = false;
		// 4.0.0

		prefixCls = prefixCls;
		showTitle = true;
		isInput = false;
		disableCloseUnderTransfer = false; // transfer 模式下，点击 slot 也会触发关闭
		tIndex = this.handleGetIndex();
		enterTimer = 0;
		get classes() {
			return [
				`${prefixCls}`,
				{
					[`${prefixCls}-confirm`]: this.confirm
				}
			];
		}
		get popperClasses() {
			return [
				`${prefixCls}-popper`,
				{
					[`${prefixCls}-confirm`]: this.transfer && this.confirm,
					[`${this.popperClass}`]: !!this.popperClass
				}
			];
		}
		get styles() {
			const style: any = {};
			if (this.width) {
				style.width = `${this.width}px`;
				//	Object.setPrototypeOf(style, { minWidth: `${this.width}px` });
			}
			//	style.minWidth = `${this.width}px`;

			if (this.transfer) {
				style["z-index"] = (1060 + this.tIndex).toString();
				//style.zIndex = (1060 + this.tIndex).toString();
				/* 	Object.setPrototypeOf(style, {
							"z-index": (1060 + this.tIndex).toString()
						}); */
			}
			return style;
		}
		get localeOkText() {
			if (this.okText === undefined) {
				return this.l("i.poptip.okText");
			} else {
				return this.okText;
			}
		}
		get localeCancelText() {
			if (this.cancelText === undefined) {
				return this.l("i.poptip.cancelText");
			} else {
				return this.cancelText;
			}
		}
		get contentClasses() {
			return [
				`${prefixCls}-body-content`,
				{
					[`${prefixCls}-body-content-word-wrap`]: this.wordWrap
				}
			];
		}
		get contentPaddingStyle() {
			if (this.padding !== "") {
				return { padding: this.padding };
			} else {
				return {};
			}
		}

		handleClick() {
			if (this.disabled) return;

			if (this.confirm) {
				this.visible = !this.visible;
				return true;
			}
			if (this.trigger !== "click") {
				return false;
			}
			this.visible = !this.visible;
		}
		handleTransferClick() {
			if (this.transfer) this.disableCloseUnderTransfer = true;
		}
		handleClose() {
			if (this.disableCloseUnderTransfer) {
				this.disableCloseUnderTransfer = false;
				return false;
			}
			if (this.confirm) {
				this.visible = false;
				return true;
			}
			if (this.trigger !== "click") {
				return false;
			}
			this.visible = false;
		}
		handleFocus(e: Event, fromInput = true) {
			if (this.disabled) return;

			if (
				this.trigger !== "focus" ||
				this.confirm ||
				(this.isInput && !fromInput)
			) {
				return false;
			}
			this.visible = true;
		}
		handleBlur(e: Event, fromInput = true) {
			if (
				this.trigger !== "focus" ||
				this.confirm ||
				(this.isInput && !fromInput)
			) {
				return false;
			}
			this.visible = false;
		}
		handleMouseenter() {
			if (this.disabled) return;

			if (this.trigger !== "hover" || this.confirm) {
				return false;
			}
			if (this.enterTimer) clearTimeout(this.enterTimer);
			this.enterTimer = setTimeout(() => {
				this.visible = true;
			}, 100);
		}
		handleMouseleave() {
			if (this.trigger !== "hover" || this.confirm) {
				return false;
			}
			if (this.enterTimer) {
				clearTimeout(this.enterTimer);
				this.enterTimer = setTimeout(() => {
					this.visible = false;
				}, 100);
			}
		}
		cancel() {
			this.visible = false;
			this.$emit("on-cancel");
		}
		ok() {
			this.visible = false;
			this.$emit("on-ok");
		}
		getInputChildren() {
			const $input = (this.$refs.reference as HTMLElement).querySelectorAll(
				"input"
			);
			const $textarea = (this.$refs.reference as HTMLElement).querySelectorAll(
				"textarea"
			);
			let $children = null;

			if ($input.length) {
				$children = $input[0];
			} else if ($textarea.length) {
				$children = $textarea[0];
			}

			return $children;
		}
		handleGetIndex() {
			this.transferIncrease();
			return this.transferIndex;
		}
		/* 	handleIndexIncrease() {
									this.tIndex = this.handleGetIndex();
								} */

		mounted() {
			if (!this.confirm) {
				//                this.showTitle = this.$refs.title.innerHTML != `<div class="${prefixCls}-title-inner"></div>`;
				this.showTitle =
					this.$slots.title !== undefined || this.title !== undefined;
			}
			// if trigger and children is input or textarea,listen focus & blur event
			if (this.trigger === "focus") {
				this.$nextTick(() => {
					const $children = this.getInputChildren();
					if ($children) {
						this.isInput = true;
						$children.addEventListener("focus", this.handleFocus, false);
						$children.addEventListener("blur", this.handleBlur, false);
					}
				});
			}
		}
		beforeDestroy() {
			const $children = this.getInputChildren();
			if ($children) {
				$children.removeEventListener("focus", this.handleFocus, false);
				$children.removeEventListener("blur", this.handleBlur, false);
			}
		}
	}
</script>
